class ResourcesController < ApplicationController
  before_filter :authorize_author, :except => [:index]

  RESOURCE_CATEGORY_ID_TO_PROPS = {
    ResourceCategory::DOCUMENT[:id] => {
      :model => Document,
      :partial => "document",
      :name => "Document"
    },
    ResourceCategory::IMAGE[:id] => {
      :model => Image,
      :partial => "image",
      :name => "Image"
    },
    ResourceCategory::VIDEO[:id] => {
      :model => Video,
      :partial => "video",
      :name => "Video"
    },
    ResourceCategory::LINK[:id] => {
      :model => Link,
      :partial => "link",
      :name => "Link"
    }
  }

  def index
    ecase_id = params[:id]
    @ecase = Ecase.find(ecase_id)
    @selected_tab = :resources
    @documents = Document.find_all_by_ecase_id(ecase_id)
    @images = Image.find_all_by_ecase_id(ecase_id)
    @videos = Video.find_all_by_ecase_id(ecase_id)
    @links = Link.find_all_by_ecase_id(ecase_id)
    @error_resource = session[:error_resource]
    @show_edit_file = !@error_resource.nil? 

    if @show_edit_file
      session[:error_resource] = nil
      @ecase_id = ecase_id
      @resource = get_edited_resource
      @resource_categories = get_resource_categories
      @selected = @resource && @resource.category[:id]
    end
  end

  def add_file
    @ecase_id = params[:id]
    @resource_categories = get_resource_categories
    clear_edited_resource

    render :partial => "edit_file"
  end

  def edit_file
    @resource = RESOURCE_CATEGORY_ID_TO_PROPS[params[:category_id].to_i][:model].find(params[:id])
    @resource_categories = get_resource_categories
    @selected = @resource.category[:id]
    set_edited_resource(@resource)

    render :partial => "edit_file"
  end

  def on_edit_file
    resource_form = params[:resource]
    old_category_id = params[:category][:old_id].to_i
    category_id = params[:category][:id].to_i
    old_data = RESOURCE_CATEGORY_ID_TO_PROPS[old_category_id]
    new_data = RESOURCE_CATEGORY_ID_TO_PROPS[category_id]
    create = get_edited_resource.nil?
    category_changed = !(create || category_id == old_category_id)
    added_or_modified = category_changed ? "modified" : (create ? "added" : "modified")

    affected_resource_name = category_changed ? old_data[:name] : new_data[:name]
    new_model = new_data[:model]

    if resource_form[:url].length > MAX_RESOURCE_SIZE
      set_flash_info FlashInfo.get_error(affected_resource_name + " could not be " + added_or_modified + "." \
        + "\nSize of file exceeds " + format_bytes(MAX_RESOURCE_SIZE) + " limit.")
      redirect_to :action => :index, :id => resource_form[:ecase_id]
      return
    end

    # two cases: 
    #   - users edits existing resource and changes its category
    #   - user creates a new resource or edits without changing its category
    if category_changed
      resource_id = resource_form[:id]
      resource_form.delete([:id])
      resource = new_model.create(merge_author(resource_form))
      success = resource.errors.empty?

      old_data[:model].destroy(resource_id) if success
    else
      if create
        resource = new_model.create(merge_author(resource_form))
      else
        resource = new_model.find(resource_form[:id])
        resource.update_attributes(resource_form)
      end

      success = resource.errors.empty?
    end

    set_flash_info success \
      ? FlashInfo.get_notice(affected_resource_name + " successfully " + added_or_modified + ".") \
      : FlashInfo.get_error(affected_resource_name + " could not be " + added_or_modified + ".")

    clear_edited_resource if (!create && success)
    session[:error_resource] = resource unless success

    redirect_to :action => :index, :id => resource_form[:ecase_id]
  end

  def add_link
    @resource = Link.new(:ecase_id => params[:id])

    render :partial => "edit_link"
  end

  def edit_link
    @resource = Link.find(params[:id])
    @row = params[:row]
    render :partial => "edit_link"
  end

  def on_edit_link
    resource = params[:resource]

    @create = resource[:id].empty?
    added_or_modified = @create ? "added" : "modified"

    if @create
      @link = Link.create(resource.merge({:author_id => get_session_user.id}))
    else
      @link = Link.find(resource[:id])
      @row = params[:row]
      @link.update_attributes(resource)
    end

    @fi = @link.errors.empty? \
      ? FlashInfo.get_notice("Link successfully " + added_or_modified + ".") \
      : FlashInfo.get_error("Link could not be " + added_or_modified + ".")
  end

  def remove_resource
    data = RESOURCE_CATEGORY_ID_TO_PROPS[params[:category_id].to_i]
    resource = data[:model].find(params[:id])
    ecase_id = resource.ecase_id 
    resource.destroy
    set_flash_info FlashInfo.get_notice(data[:name] + " has been successfully removed.")
    redirect_to :action => :index, :id => ecase_id
  end

  private

  def get_resource_categories
    ResourceCategory.options([["Select Category", 0]]).reject {|i| i[1] == ResourceCategory::LINK[:id]}
  end
  
  def set_edited_resource(resource_)
    session[:edited_resource] = resource_
  end
  
  def get_edited_resource
    session[:edited_resource] 
  end
  
  def clear_edited_resource
    set_edited_resource(nil)
  end
  
  def merge_author(form_data_)
    form_data_.merge({:author_id => get_session_user.id})
  end
end